import {use_config_map} from "@/store/config_map.ts";
import {use_this_admin} from "@/store/this_admin.ts";
import {use_this_user} from "@/store/this_user.js";
// @ts-ignore
import {camel_str, in_right, to_string} from "@/js/s94_tool.js";
import {S94Cart} from "@/js/S94Cart.ts";

interface TypeModelAction {
    model_name: string;
    action: string;
    label: string;
    tips: string;
    operator: string;
    channel: string;
    type: string;
    need_status: string;
    need_pay_status: string;
    change_status: string;
    change_pay_status: string;
    form_param_ids: string;
    where_param_ids: string | null;
    init_need_param: string;
    need_log: number;
    base_where: string;
    base_param: string;
    is_ban: number;
    template: string | null;
    page_id: number;
    lock: number;
    config_json: string;
    config: object;
    sort: number;
    execute_ids: string | null;
    validation_json: string;
    id: number;
    create_time: string;
    delete_time: number;
    tenant_id: number;
    model_id: number;
    need_login: number;
    label_status: string | null;
    label_pay_status: string | null;
    allow_skip: number;
    batch_param: string | null;
    page_config: [];
}

function assert(pass:any, errorMessage:string){
    if (!pass) throw new Error(errorMessage);
}

export class S94Model {
    action_list: TypeModelAction[] = [];
    children_model = '';
    create_time = '';
    delete_time = 0;
    id = 0;
    info = '';
    join_json = '';
    label = '';
    name = '';
    over_action = '';
    over_status = null;
    parent_model = '';
    pay_status_map_json = '';
    status_alias_map:{
        status?: {
            [key: string]: string;
        };
        pay_status?: {
            [key: string]: string;
        };
    } = {};
    status_alias_map_json = '';
    switch: 0 | 1 = 0;
    switch_auto_action: 0 | 1 = 0;
    switch_owned: 0 | 1 = 0;
    switch_parent: 0 | 1 = 0;
    switch_pay: 0 | 1 = 0;
    switch_price: 0 | 1 = 0;
    switch_price_additional: 0 | 1 = 0;
    switch_price_sku: 0 | 1 = 0;
    switch_price_vip: 0 | 1 = 0;
    switch_quota: 0 | 1 = 0;
    switch_sales: 0 | 1 = 0;
    switch_sort: 0 | 1 = 0;
    switch_stock: 0 | 1 = 0;
    tenant_id = 0;

    constructor(data:object){
        Object.keys(data).forEach(k=>{
            // @ts-ignore
            this[k] = data[k];
        })
    }
    static find(model_name:string): S94Model | undefined {
        if (!model_name) return undefined;
        let model = use_config_map().model_map[model_name];
        if (!model) return undefined;
        return new S94Model(model);
    }
    static findOrThrow(model_name:string):S94Model{
        let model = this.find(model_name)
        if (!model) throw new Error(`模型不存在：${model_name}`);
        return model;
    }

    parentModelMap():{[name: string]: S94Model}
    {
        let res:{[name: string]: S94Model} = {};
        this.parent_model.split(',').forEach(name=>{
            let model = S94Model.find(name);
            if (model) res[name] = model;
        })
        return res;
    }
    childrenModelMap():{[name: string]: S94Model}
    {
        let res:{[name: string]: S94Model} = {};
        Object.values(use_config_map().model_map).forEach(row=>{
            let isChild = !!~row.parent_model.split(',').indexOf(this.name);
            if (isChild) res[row.name] = new S94Model(row);
        })
        return res;
    }

    /**按条件，查找第一个模型操作，没找到返回 undefined
     * @param action
     * @param type
     * @param channel
     */
    findAction(action='', type='', channel=''):TypeModelAction | undefined
    {
        return this.action_list.find(row=>{
            return (!action || action===row.action) && (!type || type===row.type) &&(!channel || channel===row.channel);
        })
    }
    findActionHome(action='', type=''):TypeModelAction | undefined
    {
        return this.findAction(action, type, 'home')
    }
    findActionAdmin(action='', type=''):TypeModelAction | undefined
    {
        return this.findAction(action, type, 'admin')
    }

    canActionList(
        info: {
            status?: any;
            pay_status?: any;
        },
        channel=''
    ):TypeModelAction[]
    {
        let res:TypeModelAction[] = [];
        this.action_list.filter((action_row)=>{
            return (!channel || channel===action_row.channel);
        }).forEach(action_row=>{
            if (action_row.is_ban==1) return;
            // 状态判断
            action_row.need_status = to_string(action_row.need_status);
            if (action_row.need_status !== ''){
                let arr = action_row.need_status.split(",");
                if (!~arr.indexOf(to_string(info.status))) return;
            }
            action_row.need_pay_status = to_string(action_row.need_pay_status);
            if (action_row.need_pay_status !== ''){
                let arr = action_row.need_pay_status.split(",");
                if (!~arr.indexOf(to_string(info.pay_status))) return;
            }
            // admin 渠道的
            if (action_row.channel === 'admin') {
                const admin = use_this_admin();
                if (!admin.id) return; // 是否登陆
                if (!in_right([camel_str(this.name), action_row.action], admin.rights)) return; //是否有对应权限
            }
            // home 渠道
            if (action_row.channel === 'home'){
                if (action_row.need_login === 1 && !use_this_user().id) return; //是否登陆
            }
            res.push(action_row);
        })
        return res;
    }
    canActionListHome(info: {
        status?: any;
        pay_status?: any;
    }){
        return this.canActionList(info, 'home')
    }
    canActionListAdmin(info: {
        status?: any;
        pay_status?: any;
    }){
        return this.canActionList(info, 'admin')
    }


    // ------------ 旧方法兼容

    first_action(type:string, is_admin:any){
        if (is_admin){
            return this.findActionAdmin('', type);
        }else {
            return this.findActionHome('', type);
        }
    }

    cart(pay_model_name:string, action:string){
        let pay_model = S94Model.find(pay_model_name);
        if (!pay_model) {
            pay_model = Object.values(this.childrenModelMap()).find((row)=>{
                return (row.switch_pay) && row.findActionHome(action,'add');
            })
        }
        if (!pay_model) return undefined;
        let add_action = pay_model.findActionHome(action, 'add');
        if (!add_action) return undefined;

        return new S94Cart(pay_model.name, add_action.action, this.name);
    }
}